SWEP.AdminSpawnable			= false
SWEP.Author					= "Bajenovskii"
SWEP.Base					= "weapon_base"
SWEP.Contact				= "bajenovskii@yahoo.com"
SWEP.HoldType				= "melee" --this is for the world model holdtype
SWEP.Instructions			= "Primary: Toggle primary rope.\nSecondary: Toggle secondary rope."
SWEP.Primary.Ammo			= "none"
SWEP.Primary.Automatic		= false
SWEP.Primary.ClipSize		= -1
SWEP.Primary.DefaultClip	= -1
SWEP.Purpose				= "Used by ninjas to climb stuff."
SWEP.Secondary.Ammo			= "none"
SWEP.Secondary.Automatic	= false
SWEP.Secondary.ClipSize		= -1
SWEP.Secondary.DefaultClip	= -1
SWEP.Spawnable				= true
SWEP.ViewModel				= "" -- models/weapons/v_crossbow.mdl
SWEP.ViewModelFOV			= 1 -- 1 makes the model hide
SWEP.WorldModel				= "models/weapons/w_crossbow.mdl" -- models/weapons/w_crossbow.mdl

GAMEMODE.NinjaRopes = GAMEMODE.NinjaRopes or {}

function SWEP:Initialize()	
	GAMEMODE:AddNinjaRope( self )
	self.min_mass = 10
	self.counter_mass = 20
	self.counter_mass_low = 20
	self.counter_mass_high = 80
	self.pullback = -1.10
	self.pullback_low = -1.10
	self.pullback_high = -1.50
	self.hooked1 = false
	self.hooked2 = false
	self.hook_ent1 = nil
	self.hook_ent2 = nil
	self.hook_ent1_offset = Vector( 0, 0, 0 )
	self.hook_ent2_offset = Vector( 0, 0, 0 )
	self.hook_pos1 = Vector( 0, 0, 0 )
	self.hook_pos2 = Vector( 0, 0, 0 )
	self.ropelength1 = 0
	self.ropelength2 = 0
	util.PrecacheSound( "weapons/crossbow/fire1.wav" )
	util.PrecacheSound( "ambient/machines/slicer3.wav" )
	self.Weapon:ResetRopes()
end

function SWEP:ResetRopes()
	self.Weapon:PrimaryRopeOff()
	self.Weapon:SecondaryRopeOff()
end

function SWEP:Reload()
	self.Weapon:ResetRopes()
	return true
end

function SWEP:IncreasePrimaryLength( num )

end

function SWEP:PrimaryRopeOn()
	if self.hooked1 then return end											-- Can't shoot when already hooked
	--self.Weapon:EmitSound( "weapons/crossbow/fire1.wav" )
	local userid = self.Owner												-- Gets owner reference
	local user_aim = userid:GetAimVector()
	local trace = {}														-- Creates a trace table
	trace.start = userid:GetShootPos()										-- Sets trace start position
	trace.endpos = userid:GetShootPos() + ( user_aim * 2500 )				-- Sets trace end position, range = constant number
	trace.filter = userid													-- Sets the trace to ignore the user of the SWEP
	local tr = util.TraceLine( trace )										-- Initiates the actual trace with the parameters stored in the trace table
	if tr.HitSky then return end
	--if not tr.HitWorld then return end										-- Past this point, the trace should have hit something solid.
	if not SERVER then return end											-- The client's doesn't have to think about this
	if tr.HitWorld then
		self.hook_ent1 = nil
		self.enthook1 = false
		userid:SetAnimation( PLAYER_ATTACK1 )
		local user_pos = userid:GetPos()
		self.hooked1 = true														-- It's hooked all right
		self.hook_pos1 = tr.HitPos												-- Set hit position
		local tension = self.hook_pos1 - user_pos
		self.ropelength1 = math.sqrt(tension.x*tension.x + tension.y*tension.y + tension.z*tension.z)
		self.ropelength1_original = self.ropelength1
		
		self.piton1 = ents.Create( "prop_physics" )
		self.piton1:SetModel( "models/kunai.mdl" ) --"models/props_junk/GlassBottle01a.mdl" "models/kunai.mdl"
		self.piton1:SetPos( self.hook_pos1 + ( user_aim * -2.0 ) )
		self.piton1:SetAngles( ( -1.0 * user_aim ):Angle() )
		self.piton1:Spawn()
		self.piton1:EmitSound( "weapons/crossbow/hit1.wav" )
		self.piton1:SetKeyValue( "targetname", "vip_piton1" )
		self.piton1:SetMoveType(MOVETYPE_NONE)
		local physent = self.piton1:GetPhysicsObject()
		physent:EnableMotion(false)
		
		self.ropekeyframe1 = ents.Create( "keyframe_rope" )
		self.ropekeyframe1:SetKeyValue( "MoveSpeed", "64" )
		self.ropekeyframe1:SetKeyValue( "Slack", "-2500" )
		self.ropekeyframe1:SetKeyValue( "Subdiv", "2" )
		self.ropekeyframe1:SetKeyValue( "Width", "0.5" )
		self.ropekeyframe1:SetKeyValue( "TextureScale", "1" )
		self.ropekeyframe1:SetKeyValue( "Collide", "1" )
		self.ropekeyframe1:SetKeyValue( "RopeMaterial", "cable/rope.vmt" )
		self.ropekeyframe1:SetKeyValue( "targetname", "ropekeyframe1" )
		self.ropekeyframe1:SetPos( self.hook_pos1 + ( user_aim * -8.0 ) )
		self.ropekeyframe1:Spawn()
		self.ropekeyframe1:Activate()
		
		self.rope1 = ents.Create( "move_rope" )
		self.rope1:SetKeyValue( "MoveSpeed", "64" )
		self.rope1:SetKeyValue( "Slack", "-2500" )
		self.rope1:SetKeyValue( "Subdiv", "2" )
		self.rope1:SetKeyValue( "Width", "0.5" )
		self.rope1:SetKeyValue( "TextureScale", "1" )
		self.rope1:SetKeyValue( "Collide", "1" )
		self.rope1:SetKeyValue( "PositionInterpolator", "2" )
		self.rope1:SetKeyValue( "NextKey", "ropekeyframe1" )
		self.rope1:SetKeyValue( "RopeMaterial", "cable/rope.vmt" )
		self.rope1:SetKeyValue( "targetname", "rope1" )
		self.rope1:SetPos( userid:GetShootPos() + Vector( 0, 0, -5 ) )
		self.rope1:Spawn()
		self.rope1:Activate()
		self.rope1:SetParent( userid )
	elseif tr.HitNonWorld and tr.Entity:IsValid() and ( not tr.Entity:IsPlayer() ) and ( not tr.Entity:IsWeapon() ) then -- Must have hit a non-world entity. Not a player either. NPCs are allright, but remember PHW24: Riding scanners is dangerous.
		local user_pos = userid:GetPos()
		self.hooked1 = true														-- It's hooked all right
		self.enthook1 = true
		self.hook_ent1 = tr.Entity
		self.hook_ent_phys1 = self.hook_ent1:GetPhysicsObject()
		if self.hook_ent_phys1:GetMass() < self.min_mass then self.Weapon:PrimaryRopeOff() return end -- Physics objects lighter than 10 tend to spazz
		self.hook_pos1 = tr.HitPos												-- Set hit position
		local tension = self.hook_pos1 - user_pos
		self.ropelength1 = math.sqrt(tension.x*tension.x + tension.y*tension.y + tension.z*tension.z)
		self.ropelength1_original = self.ropelength1
		
		local hook_ent1_offset = self.hook_pos1 + ( user_aim * -8.0 ) - self.hook_ent1:GetPos()
		self.hook_ent1_offset_forward = (self.hook_ent1:GetForward()):Dot(hook_ent1_offset)
		self.hook_ent1_offset_right = (self.hook_ent1:GetRight()):Dot(hook_ent1_offset)
		self.hook_ent1_offset_up = (self.hook_ent1:GetUp()):Dot(hook_ent1_offset)
		
		--Msg("DEBUG3\n" .. tostring(self.hook_ent1_offset_forward) .. "\n" .. tostring(self.hook_ent1_offset_right).."\n"..tostring(self.hook_ent1_offset_up) .. "\n")
		--Msg("DEBUG4\n" .. tostring(hook_ent1_offset) .. "\n")
		
		userid:SetAnimation( PLAYER_ATTACK1 )
		
		self.piton1 = ents.Create( "prop_physics" )
		self.piton1:SetModel( "models/kunai.mdl" ) --"models/props_junk/GlassBottle01a.mdl" "models/kunai.mdl"
		self.piton1:SetPos( self.hook_pos1 + ( user_aim * -2.0 ) )
		self.piton1:SetAngles( ( -1.0 * user_aim ):Angle() )
		self.piton1:Spawn()
		self.piton1:SetParent(self.hook_ent1)
		self.piton1:EmitSound( "weapons/crossbow/hit1.wav" )
		self.piton1:SetKeyValue( "targetname", "vip_piton1" )
		self.piton1:SetMoveType(MOVETYPE_NONE)
		local physent = self.piton1:GetPhysicsObject()
		physent:EnableMotion(false)
		physent:EnableCollisions(false)
		
		self.ropekeyframe1 = ents.Create( "keyframe_rope" )
		self.ropekeyframe1:SetKeyValue( "MoveSpeed", "64" )
		self.ropekeyframe1:SetKeyValue( "Slack", "-2500" )
		self.ropekeyframe1:SetKeyValue( "Subdiv", "2" )
		self.ropekeyframe1:SetKeyValue( "Width", "0.5" )
		self.ropekeyframe1:SetKeyValue( "TextureScale", "1" )
		self.ropekeyframe1:SetKeyValue( "Collide", "1" )
		self.ropekeyframe1:SetKeyValue( "RopeMaterial", "cable/rope.vmt" )
		self.ropekeyframe1:SetKeyValue( "targetname", "ropekeyframe1" )
		self.ropekeyframe1:SetPos( self.hook_pos1 + ( user_aim * -8.0 ) )
		self.ropekeyframe1:Spawn()
		self.ropekeyframe1:SetParent(self.hook_ent1)
		self.ropekeyframe1:Activate()
		
		self.rope1 = ents.Create( "move_rope" )
		self.rope1:SetKeyValue( "MoveSpeed", "64" )
		self.rope1:SetKeyValue( "Slack", "-2500" )
		self.rope1:SetKeyValue( "Subdiv", "2" )
		self.rope1:SetKeyValue( "Width", "0.5" )
		self.rope1:SetKeyValue( "TextureScale", "1" )
		self.rope1:SetKeyValue( "Collide", "1" )
		self.rope1:SetKeyValue( "PositionInterpolator", "2" )
		self.rope1:SetKeyValue( "NextKey", "ropekeyframe1" )
		self.rope1:SetKeyValue( "RopeMaterial", "cable/rope.vmt" )
		self.rope1:SetKeyValue( "targetname", "rope1" )
		self.rope1:SetPos( userid:GetShootPos() + Vector( 0, 0, -5 ) )
		self.rope1:Spawn()
		self.rope1:Activate()
		self.rope1:SetParent( userid )
	else
		return
	end
end

function SWEP:PrimaryRopeOff()
	if self.hooked1 then
		self.hooked1 = false
		if self.ropekeyframe1:IsValid() then self.ropekeyframe1:Remove() end
		if self.rope1:IsValid() then self.rope1:Remove() end
		if ( self.piton1:IsValid() ) then
			self.piton1:EmitSound( "ambient/machines/slicer3.wav" )
			self.piton1:Remove()
		end
		self.enthook1 = false
		self.hook_ent1 = nil
		self.hook_ent_phys1 = nil
		self.hook_ent1_offset = Vector( 0, 0, 0 )
		self.hook_pos1 = Vector( 0, 0, 0 )
		self.ropelength1 = 0
		self.hook_ent1_offset_forward = 0
		self.hook_ent1_offset_right = 0
		self.hook_ent1_offset_up = 0
	end
end

function SWEP:PrimaryRopeToggle()
	if self.hooked1 then
		self.Weapon:PrimaryRopeOff()
	else
		self.Weapon:PrimaryRopeOn()
	end
end

function SWEP:PrimaryAttack()
	self.Weapon:PrimaryRopeToggle()
end

function SWEP:SecondaryRopeOn()
	if self.hooked2 then return end											-- Can't shoot when already hooked
	--self.Weapon:EmitSound( "weapons/crossbow/fire1.wav" )
	local userid = self.Owner												-- Gets owner reference
	local user_aim = userid:GetAimVector()
	local trace = {}														-- Creates a trace table
	trace.start = userid:GetShootPos()										-- Sets trace start position
	trace.endpos = userid:GetShootPos() + ( user_aim * 2500 )				-- Sets trace end position, range = constant number
	trace.filter = userid													-- Sets the trace to ignore the user of the SWEP
	local tr = util.TraceLine( trace )										-- Initiates the actual trace with the parameters stored in the trace table
	if tr.HitSky then return end
	--if not tr.HitWorld then return end										-- Past this point, the trace should have hit something solid.
	if not SERVER then return end											-- The client's doesn't have to think about this
	if tr.HitWorld then
		self.hook_ent2 = nil
		self.enthook2 = false
		userid:SetAnimation( PLAYER_ATTACK1 )
		local user_pos = userid:GetPos()
		self.hooked2 = true														-- It's hooked all right
		self.hook_pos2 = tr.HitPos												-- Set hit position
		local tension = self.hook_pos2 - user_pos
		self.ropelength2 = math.sqrt(tension.x*tension.x + tension.y*tension.y + tension.z*tension.z)
		self.ropelength2_original = self.ropelength2
		
		self.piton2 = ents.Create( "prop_physics" )
		self.piton2:SetModel( "models/kunai.mdl" ) --"models/props_junk/GlassBottle01a.mdl" "models/kunai.mdl"
		self.piton2:SetPos( self.hook_pos2 + ( user_aim * -2.0 ) )
		self.piton2:SetAngles( ( -1.0 * user_aim ):Angle() )
		self.piton2:Spawn()
		self.piton2:EmitSound( "weapons/crossbow/hit1.wav" )
		self.piton2:SetKeyValue( "targetname", "vip_piton2" )
		self.piton2:SetMoveType(MOVETYPE_NONE)
		local physent = self.piton2:GetPhysicsObject()
		physent:EnableMotion(false)
		
		self.ropekeyframe2 = ents.Create( "keyframe_rope" )
		self.ropekeyframe2:SetKeyValue( "MoveSpeed", "64" )
		self.ropekeyframe2:SetKeyValue( "Slack", "-2500" )
		self.ropekeyframe2:SetKeyValue( "Subdiv", "2" )
		self.ropekeyframe2:SetKeyValue( "Width", "0.5" )
		self.ropekeyframe2:SetKeyValue( "TextureScale", "1" )
		self.ropekeyframe2:SetKeyValue( "Collide", "1" )
		self.ropekeyframe2:SetKeyValue( "RopeMaterial", "cable/rope.vmt" )
		self.ropekeyframe2:SetKeyValue( "targetname", "ropekeyframe2" )
		self.ropekeyframe2:SetPos( self.hook_pos2 + ( user_aim * -8.0 ) )
		self.ropekeyframe2:Spawn()
		self.ropekeyframe2:Activate()
		
		self.rope2 = ents.Create( "move_rope" )
		self.rope2:SetKeyValue( "MoveSpeed", "64" )
		self.rope2:SetKeyValue( "Slack", "-2500" )
		self.rope2:SetKeyValue( "Subdiv", "2" )
		self.rope2:SetKeyValue( "Width", "0.5" )
		self.rope2:SetKeyValue( "TextureScale", "1" )
		self.rope2:SetKeyValue( "Collide", "1" )
		self.rope2:SetKeyValue( "PositionInterpolator", "2" )
		self.rope2:SetKeyValue( "NextKey", "ropekeyframe2" )
		self.rope2:SetKeyValue( "RopeMaterial", "cable/rope.vmt" )
		self.rope2:SetKeyValue( "targetname", "rope2" )
		self.rope2:SetPos( userid:GetShootPos() + Vector( 0, 0, -5 ) )
		self.rope2:Spawn()
		self.rope2:Activate()
		self.rope2:SetParent( userid )
	elseif tr.HitNonWorld and tr.Entity:IsValid() and ( not tr.Entity:IsPlayer() ) and ( not tr.Entity:IsWeapon() ) then -- Must have hit a non-world entity. Not a player either. NPCs are allright, but remember PHW24: Riding scanners is dangerous.
		local user_pos = userid:GetPos()
		self.hooked2 = true														-- It's hooked all right
		self.enthook2 = true
		self.hook_ent2 = tr.Entity
		self.hook_ent_phys2 = self.hook_ent2:GetPhysicsObject()
		if self.hook_ent_phys2:GetMass() < self.min_mass then self.Weapon:SecondaryRopeOff() return end -- Physics objects lighter than 10 tend to spazz
		self.hook_pos2 = tr.HitPos												-- Set hit position
		local tension = self.hook_pos2 - user_pos
		self.ropelength2 = math.sqrt(tension.x*tension.x + tension.y*tension.y + tension.z*tension.z)
		self.ropelength2_original = self.ropelength2
		
		local hook_ent2_offset = self.hook_pos2 + ( user_aim * -8.0 ) - self.hook_ent2:GetPos()
		self.hook_ent2_offset_forward = (self.hook_ent2:GetForward()):Dot(hook_ent2_offset)
		self.hook_ent2_offset_right = (self.hook_ent2:GetRight()):Dot(hook_ent2_offset)
		self.hook_ent2_offset_up = (self.hook_ent2:GetUp()):Dot(hook_ent2_offset)
		
		userid:SetAnimation( PLAYER_ATTACK1 )
		
		self.piton2 = ents.Create( "prop_physics" )
		self.piton2:SetModel( "models/kunai.mdl" ) --"models/props_junk/GlassBottle01a.mdl" "models/kunai.mdl"
		self.piton2:SetPos( self.hook_pos2 + ( user_aim * -2.0 ) )
		self.piton2:SetAngles( ( -1.0 * user_aim ):Angle() )
		self.piton2:Spawn()
		self.piton2:SetParent(self.hook_ent2)
		self.piton2:EmitSound( "weapons/crossbow/hit1.wav" )
		self.piton2:SetKeyValue( "targetname", "vip_piton2" )
		self.piton2:SetMoveType(MOVETYPE_NONE)
		local physent = self.piton2:GetPhysicsObject()
		physent:EnableMotion(false)
		physent:EnableCollisions(false)
		
		self.ropekeyframe2 = ents.Create( "keyframe_rope" )
		self.ropekeyframe2:SetKeyValue( "MoveSpeed", "64" )
		self.ropekeyframe2:SetKeyValue( "Slack", "-2500" )
		self.ropekeyframe2:SetKeyValue( "Subdiv", "2" )
		self.ropekeyframe2:SetKeyValue( "Width", "0.5" )
		self.ropekeyframe2:SetKeyValue( "TextureScale", "1" )
		self.ropekeyframe2:SetKeyValue( "Collide", "1" )
		self.ropekeyframe2:SetKeyValue( "RopeMaterial", "cable/rope.vmt" )
		self.ropekeyframe2:SetKeyValue( "targetname", "ropekeyframe2" )
		self.ropekeyframe2:SetPos( self.hook_pos2 + ( user_aim * -8.0 ) )
		self.ropekeyframe2:Spawn()
		self.ropekeyframe2:SetParent(self.hook_ent2)
		self.ropekeyframe2:Activate()
		
		self.rope2 = ents.Create( "move_rope" )
		self.rope2:SetKeyValue( "MoveSpeed", "64" )
		self.rope2:SetKeyValue( "Slack", "-2500" )
		self.rope2:SetKeyValue( "Subdiv", "2" )
		self.rope2:SetKeyValue( "Width", "0.5" )
		self.rope2:SetKeyValue( "TextureScale", "1" )
		self.rope2:SetKeyValue( "Collide", "1" )
		self.rope2:SetKeyValue( "PositionInterpolator", "2" )
		self.rope2:SetKeyValue( "NextKey", "ropekeyframe2" )
		self.rope2:SetKeyValue( "RopeMaterial", "cable/rope.vmt" )
		self.rope2:SetKeyValue( "targetname", "rope2" )
		self.rope2:SetPos( userid:GetShootPos() + Vector( 0, 0, -5 ) )
		self.rope2:Spawn()
		self.rope2:Activate()
		self.rope2:SetParent( userid )
	else
		return
	end
end

function SWEP:SecondaryRopeOff()
	if self.hooked2 then
		self.hooked2 = false
		if self.ropekeyframe2:IsValid() then self.ropekeyframe2:Remove() end
		if self.rope2:IsValid() then self.rope2:Remove() end
		if ( self.piton2:IsValid() ) then
			self.piton2:EmitSound( "ambient/machines/slicer3.wav" )
			self.piton2:Remove()
		end
		self.enthook2 = false
		self.hook_ent2 = nil
		self.hook_ent_phys2 = nil
		self.hook_ent2_offset = Vector( 0, 0, 0 )
		self.hook_pos2 = Vector( 0, 0, 0 )
		self.ropelength2 = 0
		self.hook_ent2_offset_forward = 0
		self.hook_ent2_offset_right = 0
		self.hook_ent2_offset_up = 0
	end
end

function SWEP:SecondaryRopeToggle()
	if self.hooked2 then
		self.Weapon:SecondaryRopeOff()
	else
		self.Weapon:SecondaryRopeOn()
	end
end

function SWEP:SecondaryAttack()
	self.Weapon:SecondaryRopeToggle()
end

function GAMEMODE:AddNinjaRope( swep )
	table.insert( GAMEMODE.NinjaRopes, swep )
end

function GAMEMODE:NinjaRopesThink( )
	for i, swep in pairs(GAMEMODE.NinjaRopes) do
		
		if swep:IsValid() then
			if swep.Owner and swep.Owner:IsValid() then
			
				if swep.hooked1 or swep.hooked2 then -- Level 3: Hooked, general 
					
					local userid = swep.Owner
					local user_pos = userid:GetPos()
					local ropeforce1 = Vector(0,0,0)
					local ropeforce2 = Vector(0,0,0)
					
					if userid:KeyDown(IN_SPEED) and ( swep.counter_mass ~= swep.counter_mass_high ) then
						swep.counter_mass = swep.counter_mass_high
						swep.pullback = swep.pullback_high
					elseif ( not userid:KeyDown(IN_SPEED) ) and ( swep.counter_mass ~= swep.counter_mass_low ) then
						swep.counter_mass = swep.counter_mass_low
						swep.pullback = swep.pullback_low
					end
					
					if ( userid:KeyDown(IN_JUMP) and userid:KeyDown(IN_DUCK) and userid:KeyDown(IN_RELOAD) ) then
						swep.Weapon:ResetRopes()
					end
					
					if swep.hooked1 then
						if not ( swep.ropekeyframe1:IsValid() and swep.rope1:IsValid() and swep.piton1:IsValid() ) then
							swep.Weapon:PrimaryRopeOff()
						end
					elseif swep.hooked2 then
						if not ( swep.ropekeyframe2:IsValid() and swep.rope2:IsValid() and swep.piton2:IsValid() ) then
							swep.Weapon:SecondaryRopeOff()
						end
					end
					
					if swep.hooked1 and swep.hooked2 then
						local tension1 = swep.hook_pos1 - user_pos
						local stretch1 = tension1:Length()
						local tension2 = swep.hook_pos2 - user_pos
						local stretch2 = tension2:Length()
						local net_ten = (swep.hook_pos2 - swep.hook_pos1):Length()
						local net_len = swep.ropelength2 + swep.ropelength1
						
						if net_ten > net_len + 100 then
							if ( stretch1 - swep.ropelength1 > stretch2 - swep.ropelength2 ) then
								swep.Weapon:PrimaryRopeOff()
							elseif ( stretch2 - swep.ropelength2 > stretch1 - swep.ropelength1 ) then
								swep.Weapon:SecondaryRopeOff()
							else
								if math.random() > 0 then
									swep.Weapon:PrimaryRopeOff()
								else
									swep.Weapon:PrimaryRopeOff()
								end
							end
						end
						
						if ( userid:KeyDown(IN_JUMP) and ( not userid:KeyDown(IN_DUCK) ) ) then
							if ( net_ten < net_len ) then
								if ( swep.ropelength1 < 2 ) then
									swep.ropelength1 = 0
								else
									swep.ropelength1 = swep.ropelength1 - 2
									swep.ropekeyframe1:SetKeyValue( "Slack", tostring( swep.ropelength1 - swep.ropelength1_original ) )
									swep.rope1:SetKeyValue( "Slack", tostring( swep.ropelength1 - swep.ropelength1_original ) )
								end
							end
							
							if ( userid:KeyDown(IN_USE) ) then
								swep.ropelength2 = swep.ropelength2 + 2
							else
								if ( net_ten < net_len ) then
									if ( swep.ropelength2 < 2 ) then
										swep.ropelength2 = 0
									else
										swep.ropelength2 = swep.ropelength2 - 2
										swep.ropekeyframe2:SetKeyValue( "Slack", tostring( swep.ropelength2 - swep.ropelength2_original ) )
										swep.rope2:SetKeyValue( "Slack", tostring( swep.ropelength2 - swep.ropelength2_original ) )
									end
								end
							end
						elseif ( userid:KeyDown(IN_DUCK) and ( not userid:KeyDown(IN_JUMP) ) ) then
							swep.ropelength1 = swep.ropelength1 + 2
							
							if ( userid:KeyDown(IN_USE) ) then
								if ( net_ten < net_len ) then
									if ( swep.ropelength2 < 2 ) then
										swep.ropelength2 = 0
									else
										swep.ropelength2 = swep.ropelength2 - 2
										swep.ropekeyframe2:SetKeyValue( "Slack", tostring( swep.ropelength2 - swep.ropelength2_original ) )
										swep.rope2:SetKeyValue( "Slack", tostring( swep.ropelength2 - swep.ropelength2_original ) )
									end
								end
							else
								swep.ropelength2 = swep.ropelength2 + 2
							end
						end
					end
					
					if swep.hooked1 then -- Level 4, hooked #1
						-- New swep.hook_pos1 has to be defined is the rope is attached to a possibly-moving entity
						if swep.enthook1 then -- Level 5, enthooked #1
							if not swep.hook_ent1:IsValid() then swep.Weapon:PrimaryRopeOff() return end
							
							swep.hook_pos1 = swep.hook_ent1:GetPos() + swep.hook_ent1_offset_forward*swep.hook_ent1:GetForward() + swep.hook_ent1_offset_right*swep.hook_ent1:GetRight() + swep.hook_ent1_offset_up*swep.hook_ent1:GetUp()
							
						end
						
						local tension = swep.hook_pos1 - user_pos
						local stretch = tension:Length()
						
						if not swep.hooked2 then
							if stretch > swep.ropelength1 + 100 then
								swep.Weapon:PrimaryRopeOff()
							end
							
							if (userid:KeyDown(IN_JUMP)) then
								if ( swep.ropelength1 < 2 ) then swep.ropelength1 = 0 else swep.ropelength1 = swep.ropelength1 - 2 end
								--_EntSetKeyValue(ropekeyframe,"Slack","" .. hookropelength - originalhookropelength .. "");
								--_EntSetKeyValue(rope,"Slack","" .. hookropelength - originalhookropelength .. "");
								swep.ropekeyframe1:SetKeyValue( "Slack", tostring( swep.ropelength1 - swep.ropelength1_original ) )
								swep.rope1:SetKeyValue( "Slack", tostring( swep.ropelength1 - swep.ropelength1_original ) )
							end
							
							if (userid:KeyDown(IN_DUCK)) then
								swep.ropelength1 = swep.ropelength1 + 2
							end
						end
						
						if ( swep.ropelength1 < stretch ) then
							local tension_norm = tension:GetNormal()
							local user_vel = Vector(0,0,0)
							if swep.enthook1 then
								--Msg("type(userid:GetVelocity()) = " .. type(userid:GetVelocity()) .. "\n")
								--Msg("type(swep.hook_ent_phys1) = " .. type(swep.hook_ent_phys1) .. "\n")
								--Msg("type(swep.hook_ent_phys1:GetVelocity()) = " .. type(swep.hook_ent_phys1:GetVelocity()) .. "\n")
								user_vel = userid:GetVelocity() - swep.hook_ent_phys1:GetVelocity() -- This compensates when the player is hanging on a moving object
							else
								user_vel = userid:GetVelocity()
							end
							local tension_vel_mag = tension_norm:DotProduct(user_vel)
							
							if ( tension_vel_mag < 0 ) then
								ropeforce1 = tension_norm * ( ( tension_vel_mag * -1.25 ) + ( stretch - swep.ropelength1 ) ) -- Stretched and moving the wrong way
								--userid:SetVelocity( tension_norm * ( ( tension_vel_mag * -1.6 ) + ( stretch - swep.ropelength1 ) ) )
							else
								ropeforce1 = tension_norm * ( stretch - swep.ropelength1 ) -- Stretched and moving the right way
								--userid:SetVelocity( tension_norm * ( stretch - swep.ropelength1 ) )
							end
							
							-- And for every action, there is an equal and opposite reaction...
							if swep.enthook1 then
								--local reactionforce1 = -swep.counter_mass * ropeforce1 / swep.hook_ent_phys1:GetMass()
								local reactionforce1 = -1.0 * swep.counter_mass * ropeforce1
								swep.hook_ent_phys1:ApplyForceOffset( reactionforce1, swep.hook_pos1 )
							end
						end
					end
					
					if swep.hooked2 then -- Level 4, hooked #2
						local userid = swep.Owner
						local user_pos = userid:GetPos()
						
						-- New swep.hook_pos1 has to be defined is the rope is attached to a possibly-moving entity
						if swep.enthook2 then -- Level 5, enthooked #2
							if not swep.hook_ent2:IsValid() then swep.Weapon:SecondaryRopeOff() return end
							
							swep.hook_pos2 = swep.hook_ent2:GetPos() + swep.hook_ent2_offset_forward*swep.hook_ent2:GetForward() + swep.hook_ent2_offset_right*swep.hook_ent2:GetRight() + swep.hook_ent2_offset_up*swep.hook_ent2:GetUp()
							
						end
						
						local tension = swep.hook_pos2 - user_pos
						local stretch = tension:Length()
						
						if not swep.hooked1 then
							if stretch > swep.ropelength2 + 100 then
								swep.Weapon:SecondaryRopeOff()
							end
							
							if (userid:KeyDown(IN_JUMP)) then
								if ( swep.ropelength2 < 2 ) then swep.ropelength2 = 0 else swep.ropelength2 = swep.ropelength2 - 2 end
								swep.ropekeyframe2:SetKeyValue( "Slack", tostring( swep.ropelength2 - swep.ropelength2_original ) )
								swep.rope2:SetKeyValue( "Slack", tostring( swep.ropelength2 - swep.ropelength2_original ) )
							end
							
							if (userid:KeyDown(IN_DUCK)) then
								swep.ropelength2 = swep.ropelength2 + 2
							end
						end
						
						if ( swep.ropelength2 < stretch ) then
							local tension_norm = tension:GetNormal()
							local user_vel = Vector(0,0,0)
							if swep.enthook2 then
								--Msg("type(userid:GetVelocity()) = " .. type(userid:GetVelocity()) .. "\n")
								--Msg("type(swep.hook_ent_phys2) = " .. type(swep.hook_ent_phys2) .. "\n")
								--Msg("type(swep.hook_ent_phys2:GetVelocity()) = " .. type(swep.hook_ent_phys2:GetVelocity()) .. "\n")
								user_vel = userid:GetVelocity() - swep.hook_ent_phys2:GetVelocity() -- This compensates when the player is hanging on a moving object
							else
								user_vel = userid:GetVelocity()
							end
							local tension_vel_mag = tension_norm:DotProduct(user_vel)
							
							if ( tension_vel_mag < 0 ) then
								ropeforce2 = tension_norm * ( ( tension_vel_mag * -1.25 ) + ( stretch - swep.ropelength2 ) ) -- Stretched and moving the wrong way
								--userid:SetVelocity( tension_norm * ( ( tension_vel_mag * -1.6 ) + ( stretch - swep.ropelength2 ) ) )
							else
								ropeforce2 = tension_norm * ( stretch - swep.ropelength2 ) -- Stretched and moving the right way
								--userid:SetVelocity( tension_norm * ( stretch - swep.ropelength2 ) )
							end
							
							-- And for every action, there is an equal and opposite reaction...
							if swep.enthook2 then
								--local reactionforce2 = -swep.counter_mass * ropeforce2 / swep.hook_ent_phys2:GetMass()
								local reactionforce2 = -1.0 * swep.counter_mass * ropeforce2
								swep.hook_ent_phys2:ApplyForceOffset( reactionforce2, swep.hook_pos2 )
							end
						end
					end
					userid:SetVelocity( ropeforce1 + ropeforce2 )
				end
			end
		else
			table.remove( GAMEMODE.NinjaRopes , i )
		end
	end
end
hook.Add( "Think", "NinjaRopeV2X2_Think", GAMEMODE.NinjaRopesThink )

function SWEP:Deploy()
	if SERVER then self.Weapon:SetWeaponHoldType( "melee" ) end
	return true
end

function SWEP:Holster( weapon_to_switch_to )
	--self.Weapon:ResetRopes() -- Not anymore!
	return true
end

function SWEP:OnRemove( )
	self.Weapon:ResetRopes()
	return true
end

function SWEP:OnDrop( )
	self.Weapon:ResetRopes()
	return true
end


